﻿

namespace Nop.Web.Services.Easemob
{
    // ZTImage.HttpEx
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;


    public class HttpEx
    {
        public enum RequestMethod
        {
            GET,
            POST,
            PUT,
            DELETE
        }

        private static Dictionary<string, Action<HttpWebRequest, string>> HeaderConfile = new Dictionary<string, Action<HttpWebRequest, string>>()
    {
        {
            "Accept",
            delegate(HttpWebRequest request, string value)
            {
                request.Accept = value;
            }
        },
        {
            "Connection",
            delegate(HttpWebRequest request, string value)
            {
                request.Connection = value;
            }
        },
        {
            "Content-Length",
            delegate(HttpWebRequest request, string value)
            {
                long num2 = request.ContentLength = TypeConverter.StringToLong(value, 0L);
            }
        },
        {
            "Content-Type",
            delegate(HttpWebRequest request, string value)
            {
                request.ContentType = value;
            }
        },
        {
            "Expect",
            delegate(HttpWebRequest request, string value)
            {
                request.Expect = value;
            }
        },
        {
            "Date",
            delegate(HttpWebRequest request, string value)
            {
                DateTime dateTime4 = request.Date = TypeConverter.StringToDate(value, DateTime.Now);
            }
        },
        {
            "If-Modified-Since",
            delegate(HttpWebRequest request, string value)
            {
                DateTime dateTime2 = request.IfModifiedSince = TypeConverter.StringToDate(value, DateTime.Now);
            }
        },
        {
            "Referer",
            delegate(HttpWebRequest request, string value)
            {
                request.Referer = value;
            }
        },
        {
            "Transfer-Encoding",
            delegate(HttpWebRequest request, string value)
            {
                request.TransferEncoding = value;
            }
        },
        {
            "User-Agent",
            delegate(HttpWebRequest request, string value)
            {
                request.UserAgent = value;
            }
        },
        {
            "Host",
            delegate(HttpWebRequest request, string value)
            {
                request.Host = value;
            }
        },
        {
            "Range",
            delegate(HttpWebRequest request, string value)
            {
                if (value.Length >= 9 && value[0] == 'b' && value[1] == 'y' && value[2] == 't' && value[3] == 'e' && value[4] == 's' && value[5] == '=')
                {
                    string[] array = value.Substring(6).Split(new char[1]
                    {
                        '-'
                    }, StringSplitOptions.RemoveEmptyEntries);
                    if (array.Length == 2)
                    {
                        int from = TypeConverter.StringToInt(array[0], 0);
                        int to = TypeConverter.StringToInt(array[1], 0);
                        request.AddRange(from, to);
                    }
                }
            }
        }
    };

        public static string SyncGet(string url, Dictionary<string, string> headers = null)
        {
            return new StreamReader(SyncRequestStream(RequestMethod.GET, url, null, headers)).ReadToEnd();
        }

        public static async Task<string> Get(string url, Dictionary<string, string> headers = null)
        {
            return await new StreamReader(await RequestStream(RequestMethod.GET, url, null, headers)).ReadToEndAsync();
        }

        public static string SyncGet(string url, string data, Dictionary<string, string> headers = null)
        {
            return new StreamReader(SyncGetStream(url, data, headers)).ReadToEnd();
        }

        public static async Task<string> Get(string url, string data, Dictionary<string, string> headers = null)
        {
            return await new StreamReader(await GetStream(url, data, headers)).ReadToEndAsync();
        }

        public static Stream SyncGetStream(string url, Dictionary<string, string> headers = null)
        {
            return SyncRequestStream(RequestMethod.GET, url, null, headers);
        }

        public static async Task<Stream> GetStream(string url, Dictionary<string, string> headers = null)
        {
            return await RequestStream(RequestMethod.GET, url, null, headers);
        }

        public static Stream SyncGetStream(string url, string data, Dictionary<string, string> headers = null)
        {
            if (!string.IsNullOrEmpty(data))
            {
                url = ((url.IndexOf("?") <= 0) ? (url + "?" + data) : (url + "&" + data));
            }
            return SyncRequestStream(RequestMethod.GET, url, null, headers);
        }

        public static async Task<Stream> GetStream(string url, string data, Dictionary<string, string> headers = null)
        {
            if (!string.IsNullOrEmpty(data))
            {
                url = ((url.IndexOf("?") <= 0) ? (url + "?" + data) : (url + "&" + data));
            }
            return await RequestStream(RequestMethod.GET, url, null, headers);
        }

        public static string SyncPost(string url, Dictionary<string, string> headers = null)
        {
            return new StreamReader(SyncRequestStream(RequestMethod.POST, url, null, headers)).ReadToEnd();
        }

        public static async Task<string> Post(string url, Dictionary<string, string> headers = null)
        {
            return await new StreamReader(await RequestStream(RequestMethod.POST, url, null, headers)).ReadToEndAsync();
        }

        public static string SyncPost(string url, string data, Encoding encoding, Dictionary<string, string> headers = null)
        {
            byte[] data2 = null;
            if (!string.IsNullOrEmpty(data))
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }
                data2 = encoding.GetBytes(data);
            }
            return new StreamReader(SyncRequestStream(RequestMethod.POST, url, data2, headers)).ReadToEnd();
        }

        public static async Task<string> Post(string url, string data, Encoding encoding, Dictionary<string, string> headers = null)
        {
            byte[] data2 = null;
            if (!string.IsNullOrEmpty(data))
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }
                data2 = encoding.GetBytes(data);
            }
            return await new StreamReader(await RequestStream(RequestMethod.POST, url, data2, headers)).ReadToEndAsync();
        }

        public static string SyncPost(string url, byte[] data, Dictionary<string, string> headers = null)
        {
            return new StreamReader(SyncRequestStream(RequestMethod.POST, url, data, headers)).ReadToEnd();
        }

        public static async Task<string> Post(string url, byte[] data, Dictionary<string, string> headers = null)
        {
            return await new StreamReader(await RequestStream(RequestMethod.POST, url, data, headers)).ReadToEndAsync();
        }

        public static Stream SyncPostStream(string url, Dictionary<string, string> headers = null)
        {
            return SyncRequestStream(RequestMethod.POST, url, null, headers);
        }

        public static async Task<Stream> PostStream(string url, Dictionary<string, string> headers = null)
        {
            return await RequestStream(RequestMethod.POST, url, null, headers);
        }

        public static Stream SyncPostStream(string url, string data, Encoding encoding, Dictionary<string, string> headers = null)
        {
            byte[] data2 = null;
            if (!string.IsNullOrEmpty(data))
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }
                data2 = encoding.GetBytes(data);
            }
            return SyncRequestStream(RequestMethod.POST, url, data2, headers);
        }

        public static async Task<Stream> PostStream(string url, string data, Encoding encoding, Dictionary<string, string> headers = null)
        {
            byte[] data2 = null;
            if (!string.IsNullOrEmpty(data))
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }
                data2 = encoding.GetBytes(data);
            }
            return await RequestStream(RequestMethod.POST, url, data2, headers);
        }

        public static Stream SyncPostStream(string url, byte[] data, Dictionary<string, string> headers = null)
        {
            return SyncRequestStream(RequestMethod.POST, url, data, headers);
        }

        public static async Task<Stream> PostStream(string url, byte[] data, Dictionary<string, string> headers = null)
        {
            return await RequestStream(RequestMethod.POST, url, data, headers);
        }

        public static string SyncPut(string url, Dictionary<string, string> headers = null)
        {
            return new StreamReader(SyncRequestStream(RequestMethod.PUT, url, null, headers)).ReadToEnd();
        }

        public static async Task<string> Put(string url, Dictionary<string, string> headers = null)
        {
            return await new StreamReader(await RequestStream(RequestMethod.PUT, url, null, headers)).ReadToEndAsync();
        }

        public static string SyncPut(string url, string data, Encoding encoding, Dictionary<string, string> headers = null)
        {
            byte[] data2 = null;
            if (!string.IsNullOrEmpty(data))
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }
                data2 = encoding.GetBytes(data);
            }
            return new StreamReader(SyncRequestStream(RequestMethod.PUT, url, data2, headers)).ReadToEnd();
        }

        public static async Task<string> Put(string url, string data, Encoding encoding, Dictionary<string, string> headers = null)
        {
            byte[] data2 = null;
            if (!string.IsNullOrEmpty(data))
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }
                data2 = encoding.GetBytes(data);
            }
            return await new StreamReader(await RequestStream(RequestMethod.PUT, url, data2, headers)).ReadToEndAsync();
        }

        public static string SyncPut(string url, byte[] data, Dictionary<string, string> headers = null)
        {
            return new StreamReader(SyncRequestStream(RequestMethod.PUT, url, data, headers)).ReadToEnd();
        }

        public static async Task<string> Put(string url, byte[] data, Dictionary<string, string> headers = null)
        {
            return await new StreamReader(await RequestStream(RequestMethod.PUT, url, data, headers)).ReadToEndAsync();
        }

        public static Stream SyncPutStream(string url, Dictionary<string, string> headers = null)
        {
            return SyncRequestStream(RequestMethod.PUT, url, null, headers);
        }

        public static async Task<Stream> PutStream(string url, Dictionary<string, string> headers = null)
        {
            return await RequestStream(RequestMethod.PUT, url, null, headers);
        }

        public static Stream SyncPutStream(string url, string data, Encoding encoding, Dictionary<string, string> headers = null)
        {
            byte[] data2 = null;
            if (!string.IsNullOrEmpty(data))
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }
                data2 = encoding.GetBytes(data);
            }
            return SyncRequestStream(RequestMethod.PUT, url, data2, headers);
        }

        public static async Task<Stream> PutStream(string url, string data, Encoding encoding, Dictionary<string, string> headers = null)
        {
            byte[] data2 = null;
            if (!string.IsNullOrEmpty(data))
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }
                data2 = encoding.GetBytes(data);
            }
            return await RequestStream(RequestMethod.PUT, url, data2, headers);
        }

        public static Stream SyncPutStream(string url, byte[] data, Dictionary<string, string> headers = null)
        {
            return SyncRequestStream(RequestMethod.PUT, url, data, headers);
        }

        public static async Task<Stream> PutStream(string url, byte[] data, Dictionary<string, string> headers = null)
        {
            return await RequestStream(RequestMethod.PUT, url, data, headers);
        }

        public static string SyncDelete(string url, Dictionary<string, string> headers = null)
        {
            return new StreamReader(SyncRequestStream(RequestMethod.DELETE, url, null, headers)).ReadToEnd();
        }

        public static async Task<string> Delete(string url, Dictionary<string, string> headers = null)
        {
            return await new StreamReader(await RequestStream(RequestMethod.DELETE, url, null, headers)).ReadToEndAsync();
        }

        public static Stream SyncDeleteStream(string url, Dictionary<string, string> headers = null)
        {
            return SyncRequestStream(RequestMethod.DELETE, url, null, headers);
        }

        public static async Task<Stream> DeleteStream(string url, Dictionary<string, string> headers = null)
        {
            return await RequestStream(RequestMethod.DELETE, url, null, headers);
        }

        public static Stream SyncDeleteStream(string url, string data, Dictionary<string, string> headers = null)
        {
            if (!string.IsNullOrEmpty(data))
            {
                url = ((url.IndexOf("?") <= 0) ? (url + "?" + data) : (url + "&" + data));
            }
            return SyncRequestStream(RequestMethod.DELETE, url, null, headers);
        }

        public static async Task<Stream> DeleteStream(string url, string data, Dictionary<string, string> headers = null)
        {
            if (!string.IsNullOrEmpty(data))
            {
                url = ((url.IndexOf("?") <= 0) ? (url + "?" + data) : (url + "&" + data));
            }
            return await RequestStream(RequestMethod.DELETE, url, null, headers);
        }

        private static void AddHeaders(HttpWebRequest request, Dictionary<string, string> headers)
        {
            if (request != null && headers != null && headers.Count > 0)
            {
                if (request.Headers == null)
                {
                    request.Headers = new WebHeaderCollection();
                }
                foreach (KeyValuePair<string, string> header in headers)
                {
                    if (HeaderConfile.ContainsKey(header.Key))
                    {
                        HeaderConfile[header.Key](request, header.Value);
                    }
                    else
                    {
                        request.Headers.Add(header.Key, header.Value);
                    }
                }
            }
        }

        private static Stream SyncRequestStream(RequestMethod method, string url, byte[] data, Dictionary<string, string> headers = null)
        {
            try
            {
                HttpWebRequest httpWebRequest = CreateRequest(method, url, headers);
                if (data != null && data.Length != 0)
                {
                    BinaryWriter binaryWriter = new BinaryWriter(httpWebRequest.GetRequestStream());
                    binaryWriter.Write(data);
                    binaryWriter.Flush();
                }
                HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse;
                if (httpWebResponse.StatusCode == HttpStatusCode.OK)
                {
                    return httpWebResponse.GetResponseStream();
                }
                return Stream.Null;
            }
            catch (Exception ex)
            {

                return Stream.Null;
            }
        }

        private static async Task<Stream> RequestStream(RequestMethod method, string url, byte[] data, Dictionary<string, string> headers = null)
        {
            try
            {
                HttpWebRequest request = CreateRequest(method, url, headers);
                if (data != null && data.Length != 0)
                {
                    BinaryWriter binaryWriter = new BinaryWriter(await request.GetRequestStreamAsync());
                    binaryWriter.Write(data);
                    binaryWriter.Flush();
                }
                HttpWebResponse httpWebResponse = (await request.GetResponseAsync()) as HttpWebResponse;
                if (httpWebResponse.StatusCode == HttpStatusCode.OK)
                {
                    return httpWebResponse.GetResponseStream();
                }
                return Stream.Null;
            }
            catch (Exception ex)
            {

                return Stream.Null;
            }
        }

        private static HttpWebRequest CreateRequest(RequestMethod method, string url, Dictionary<string, string> headers)
        {
            HttpWebRequest httpWebRequest = WebRequest.CreateHttp(url);
            switch (method)
            {
                case RequestMethod.POST:
                    httpWebRequest.Method = "POST";
                    break;
                case RequestMethod.GET:
                    httpWebRequest.Method = "GET";
                    break;
                case RequestMethod.DELETE:
                    httpWebRequest.Method = "DELETE";
                    break;
                case RequestMethod.PUT:
                    httpWebRequest.Method = "PUT";
                    break;
            }
            AddHeaders(httpWebRequest, headers);
            return httpWebRequest;
        }
    }

}
